home *** CD-ROM | disk | FTP | other *** search
/ PD ROM 1 / PD ROM Volume I - Macintosh Software from BMUG (1988).iso / Programming / Complete Applications / Screen Savers / ZoomIdle (C) / ZoomIdle.c next >
Encoding:
C/C++ Source or Header  |  1986-07-31  |  5.9 KB  |  247 lines  |  [TEXT/ttxt]

  1. /* Written  9:30 am  Jul 26, 1986 by dubois@uwmacc.UUCP in uiucdcsb:mod.mac.sources */
  2. Here is the LightspeedC source to ZoomIdle1.1.  For printing, tab
  3. size should be 4.
  4. --- cut ---
  5. /*
  6.     ZoomIdle
  7.     Version 1.1     25 July 1986
  8.  
  9.     Screen saver desk accessory.  Generates successive randomly chosen
  10.     rectangles, and zooms each into the next by interpolating a series
  11.     of rectangles intermediate in shape and location.  Click and hold in
  12.     menu bar to pause the display.  Click below menu bar to terminate.
  13.  
  14.     The project should include MacTraps and ZoomIdle1.1.c.  The project
  15.     type should be Desk Accessory.
  16.  
  17.     Changes since 1.0:
  18.  
  19.     Works with Macintosh XL (wider screen).
  20.     Doesn't clear the menu bar until the window receives an activate
  21.     event.  1.0 cleared the bar immediately, which was too early -
  22.     some programs would crash when ZoomIdle exited.
  23.  
  24.  
  25.     Paul DuBois
  26.     Wisconsin Regional Primate Research Center
  27.     1220 Capitol Court
  28.     University of Wisconsin-Madison
  29.     Madison, WI  53706
  30.  
  31.     UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois
  32.     ARPA: dubois@easter
  33.           dubois@unix.macc.wisc.edu
  34. */
  35.  
  36.  
  37. # include    <DeviceMgr.h>
  38. # include    <WindowMgr.h>    /* includes QuickDraw.h, MacTypes.h */
  39. # include    <EventMgr.h>
  40. # include    <MenuMgr.h>
  41.  
  42. # define    nil            0L
  43.  
  44.  
  45. /*
  46.     zoomSteps controls the number of rectangles that are drawn in each
  47.     interpolative series.  zoomShow controls how many rectangles are
  48.     visible at once.  These two values may be varied independently, but
  49.     they must both be greater than zero.
  50. */
  51.  
  52. # define    zoomSteps    15
  53. # define    zoomShow    15
  54.  
  55.  
  56. /*  global variables  */
  57.  
  58. Rect        zRect[zoomShow];
  59. int            zIndex;
  60.  
  61.  
  62. /*
  63.     Return integer between zero and max (inclusive).  Assumes max is
  64.     non-negative.
  65. */
  66.  
  67.  
  68. Rand (max)
  69. int    max;
  70. {
  71. register int    t;
  72.  
  73.     if ((t = Random ()) < 0) t = -t;
  74.     return (t % (max + 1));
  75. }
  76.  
  77.  
  78. /*
  79.     Interpolate one rectangle smoothly into another.  This algorithm
  80.     assumes that it is erasing the previous series while it's
  81.     drawing the new one.  The first time this is called, that is not
  82.     true, which is why the init code sets all the zRect rectangles
  83.     empty - it's harmless to erase empty rectangles (doesn't show on
  84.     screen).
  85.     
  86.     Pen mode should be set to patXor, so that the first drawing shows
  87.     the rectangle, the second time erases it.  Gray seems to work
  88.     best for the pen pattern:  white is too stark a contrast, except
  89.     perhaps for the very dialectic.
  90. */
  91.  
  92. ZoomRect (r1, r2)
  93. Rect    r1, r2;
  94.  
  95. {
  96. register int    r1left, r1top;
  97. register int    l, t;
  98. register int    j;
  99. int                hDiff, vDiff, widDiff, htDiff;
  100. int                r, b;
  101. int                rWid, rHt;
  102. register Rect    *rp;
  103.  
  104.     r1left = r1.left;
  105.     r1top = r1.top;
  106.     hDiff = r2.left - r1left;    /* positive if moving to right */
  107.     vDiff = r2.top - r1top;        /* positive if moving down */
  108.     rWid = r1.right - r1left;
  109.     rHt = r1.bottom - r1top;
  110.     widDiff = (r2.right - r2.left) - rWid;
  111.     htDiff = (r2.bottom - r2.top) - rHt;
  112.  
  113. /*
  114.     order of evaluation is important in the rect coordinate calculations.
  115.     since all arithmetic is integer, you can't save time by calculating
  116.     j/zoomSteps and using that - it'll usually be zero.
  117. */
  118.  
  119.     for (j = 1; j <= zoomSteps; j++)
  120.     {
  121.         if (++zIndex >= zoomShow)
  122.             zIndex = 0;
  123.         rp = &zRect[zIndex];
  124.         FrameRect (rp);                /* erase a rectangle */
  125.         l = r1left + (hDiff * j) / zoomSteps;
  126.         t = r1top + (vDiff * j) / zoomSteps;
  127.         r = l + rWid + (widDiff * j) / zoomSteps;
  128.         b = t + rHt + (htDiff * j) / zoomSteps;
  129.         SetRect (rp, l, t, r, b);
  130.         FrameRect (rp);
  131.     }
  132.         
  133. }
  134.  
  135.  
  136. main(p, d, n)
  137. cntrlParam *p;    /*  ==> parameter block  */
  138. DCtlPtr d;        /*  ==> device control entry  */
  139. int n;            /*  entry point selector  */
  140.  
  141. {
  142. register DCtlPtr    dce = d;
  143. Rect                dstRect;
  144. Point                pt1, pt2;
  145. long                pat[2];
  146. static int            scrnSizeX;
  147. static int            scrnSizeY;
  148. static Rect            srcRect;
  149. static Handle        theMenuBar;
  150. static WindowPtr    theWind;
  151. static Boolean        zoomAway = false;
  152.  
  153.  
  154.     /*  check to make sure our data area was allocated  */
  155.         
  156.     if (dce->dCtlStorage == 0)
  157.     {
  158.         if (n == 0)                        /*  open  */
  159.             CloseDriver(dce->dCtlRefNum);
  160.     }
  161.     else switch (n)    /*  dispatch  */
  162.     {
  163.         case 0:        /*  open  */
  164.  
  165.             dce->dCtlFlags |= dNeedLock | dNeedTime;
  166.             dce->dCtlDelay = 0;
  167.             dce->dCtlEMask = everyEvent;
  168.         
  169.             GetWMgrPort (&theWind);
  170.             srcRect = theWind->portRect;
  171.             scrnSizeX = srcRect.right;    /* get size of screen */
  172.             scrnSizeY = srcRect.bottom;
  173.             theWind = NewWindow (nil, &srcRect, "\p", true,
  174.                                     noGrowDocProc, -1L, true, 0L);
  175.             RectRgn (theWind->visRgn, &srcRect);
  176.             ((WindowPeek) theWind)->windowKind = dce->dCtlRefNum;
  177.         
  178. /*
  179.             Initialize the rect array.  This also sets zIndex
  180.             to a value that causes it to reset to zero on the
  181.             first call to ZoomRect.
  182. */
  183.             for (zIndex = 0; zIndex < zoomShow; ++zIndex)
  184.                 SetRect (&zRect[zIndex], 0, 0, 0, 0);
  185.  
  186.             break;
  187.  
  188.         case 2:        /*  control  */
  189.  
  190.             SetPort (theWind);
  191.             switch (p->csCode)
  192.             {
  193.                 case accEvent:    /* put glasses on to read next switch */
  194.  
  195.                     switch (((EventRecord *) * (long *) &p->csParam)->what)
  196.                     {
  197.                         case activateEvt:
  198.  
  199.                             theMenuBar = GetMenuBar ();
  200.                             ClearMenuBar ();
  201.                             PaintRect (&srcRect /* = &theWind->portRect */);
  202.                             PenMode (patXor);    /* do all drawing in xor */
  203.                             pat[0] = pat[1] = 0xaa55aa55L;
  204.                             PenPat (&pat);    /* can't use QD global pats! */
  205.                             zoomAway = true;
  206.                             break;
  207.  
  208.                         case mouseDown:    /* quit on mousedown event */
  209.  
  210.                             CloseDriver(dce->dCtlRefNum);
  211.                             break;
  212.                     }
  213.                     break;
  214.  
  215.                 case accRun:
  216.  
  217.                     if (zoomAway)    /* activated */
  218.                     {
  219.                         ObscureCursor ();    /* keep cursor hidden */
  220.                         pt1.h = Rand (scrnSizeX);    /* generate rect and zoom to it */
  221.                         pt1.v = Rand (scrnSizeY);
  222.                         pt2.h = Rand (scrnSizeX);
  223.                         pt2.v = Rand (scrnSizeY);
  224.                         Pt2Rect (pt1, pt2, &dstRect);
  225.                         ZoomRect (srcRect, dstRect);
  226.                         srcRect = dstRect;
  227.                     }
  228.                     break;
  229.             }
  230.             break;
  231.  
  232.         case 4:        /*  close  */
  233.  
  234.             DisposeWindow (theWind);
  235.             SetMenuBar (theMenuBar);    /* restore menu bar */
  236.             DisposHandle (theMenuBar);
  237.             DrawMenuBar ();
  238.             break;
  239.     }
  240.     
  241.     /*  done  */
  242.     
  243.     return(0);
  244. }
  245. --- end ---
  246. /* End of text from uiucdcsb:mod.mac.sources */
  247.